using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using MB.MyShare.DAL;

namespace MB.MyShare.BLL.Movies
{
   public class Movie : BaseMovie
   {
      private int _categoryID = 0;
      public int CategoryID
      {
         get { return _categoryID; }
         set { _categoryID = value; }
      }

      private string _categoryTitle = "";
      public string CategoryTitle
      {
         get { return _categoryTitle; }
         private set { _categoryTitle = value; }
      }

      private Category _category = null;
      public Category Category
      {
         get
         {
            if (_category == null)
               _category = Category.GetCategoryByID(this.CategoryID);
            return _category;
         }
      }

      private string _title = "";
      public string Title
      {
         get { return _title; }
         set { _title = value; }
      }

      private string _abstract = "";
      public string Abstract
      {
         get { return _abstract; }
         set { _abstract = value; }
      }

      private string _summary = null;
      public string Summary
      {
         get
         {
            if (_summary == null)
               _summary = SiteProvider.Movies.GetMovieSummary(this.ID);
            return _summary;
         }
         set { _summary = value; }
      }

      private string _country = "";
      public string Country
      {
         get { return _country; }
         set { _country = value; }
      }

      private string _state = "";
      public string State
      {
         get { return _state; }
         set { _state = value; }
      }

      private string _city = "";
      public string City
      {
         get { return _city; }
         set { _city = value; }
      }

      private bool _approved = true;
      public bool Approved
      {
         get { return _approved; }
         set { _approved = value; }
      }

      private int _viewCount = 0;
      public int ViewCount
      {
         get { return _viewCount; }
         private set { _viewCount = value; }
      }

//needs editing
      public Movie(int id, DateTime addedDate, string addedBy, 
         int categoryID, string categoryTitle, string title, string artabstract, 
         string summary, string country, string state, string city,
         DateTime releaseDate, DateTime expireDate, bool approved, 
         bool listed, bool commentsEnabled, bool onlyForMembers,
         int viewCount, int votes, int totalRating)
      {
         this.ID = id;
         this.AddedDate = addedDate;
         this.AddedBy = addedBy;
         this.CategoryID = categoryID;
         this.CategoryTitle = categoryTitle;
         this.Title = title;
         this.Abstract = artabstract;
         this.Summary = summary;
         this.Country = country;
         this.State = state;
         this.City = city;
         this.ReleaseDate = releaseDate;
         this.ExpireDate = expireDate;
         this.Approved = approved;
         this.Listed = listed;
         this.CommentsEnabled = commentsEnabled;
         this.OnlyForMembers = onlyForMembers;
         this.ViewCount = viewCount;
         this.Votes = votes;
         this.TotalRating = totalRating;
      }

      public bool Delete()
      {
         bool success = Movie.DeleteMovie(this.ID);         
         if (success)
            this.ID = 0;
         return success;
      }
//needs editing
      public bool Update()
      { 
         return Movie.UpdateMovie(this.ID, this.CategoryID, this.Title, 
            this.Abstract, this.Summary, this.Country, this.State, this.City,
            this.ReleaseDate, this.ExpireDate, this.Approved, this.Listed,
            this.CommentsEnabled, this.OnlyForMembers);
      }

      public bool Approve()
      {
         bool success = Movie.ApproveMovie(this.ID);
         if (success)
            this.Approved = true;
         return success;
      }

      public bool IncrementViewCount()
      {
         return Movie.IncrementMovieViewCount(this.ID);
      }


      /***********************************
      * Static methods
      ************************************/

      /// <summary>
      /// Returns a collection with all movies
      /// </summary>
      public static List<Movie> GetMovies()
      {
         return GetMovies(0, BizObject.MAXROWS);
      }
      public static List<Movie> GetMovies(int startRowIndex, int maximumRows)
      {
         List<Movie> movies = null;
         string key = "Movies_Movies_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movies = (List<Movie>)BizObject.Cache[key];
         }
         else
         {
            List<MovieDetails> recordset = SiteProvider.Movies.GetMovies(
               GetPageIndex(startRowIndex, maximumRows), maximumRows);
            movies = GetMovieListFromMovieDetailsList(recordset);
            BaseMovie.CacheData(key, movies);
         }
         return movies;
      }

      /// <summary>
      /// Returns a collection with all movies for the specified category
      /// </summary>
      public static List<Movie> GetMovies(int categoryID)
      {
         return GetMovies(categoryID, 0, BizObject.MAXROWS);
      }
      public static List<Movie> GetMovies(int categoryID, int startRowIndex, int maximumRows)
      {
         if (categoryID <= 0)
            return GetMovies(startRowIndex, maximumRows);

         List<Movie> movies = null;
         string key = "Movies_Movies_" + categoryID.ToString() + "_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movies = (List<Movie>)BizObject.Cache[key];
         }
         else
         {
            List<MovieDetails> recordset = SiteProvider.Movies.GetMovies(categoryID,
               GetPageIndex(startRowIndex, maximumRows), maximumRows);
            movies = GetMovieListFromMovieDetailsList(recordset);
            BaseMovie.CacheData(key, movies);
         }
         return movies;
      }

      /// <summary>
      /// Returns the number of total movies
      /// </summary>
      public static int GetMovieCount()
      {
         int movieCount = 0;
         string key = "Movies_MovieCount";

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movieCount = (int)BizObject.Cache[key];
         }
         else
         {
            movieCount = SiteProvider.Movies.GetMovieCount();
            BaseMovie.CacheData(key, movieCount);
         }
         return movieCount;
      }
//needs updating
      /// <summary>
      /// Returns the number of total movies for the specified category
      /// </summary>
      public static int GetMovieCount(int categoryID)
      {
         if (categoryID <= 0)
            return GetMovieCount();

         int movieCount = 0;
         string key = "Movies_MovieCount_" + categoryID.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movieCount = (int)BizObject.Cache[key];
         }
         else
         {
            movieCount = SiteProvider.Movies.GetMovieCount(categoryID);
            BaseMovie.CacheData(key, movieCount);
         }
         return movieCount;
      }

      /// <summary>
      /// Returns a collection with all published movies
      /// </summary>
      public static List<Movie> GetMovies(bool publishedOnly)
      {
         return GetMovies(publishedOnly, 0, BizObject.MAXROWS);
      }
      public static List<Movie> GetMovies(bool publishedOnly, int startRowIndex, int maximumRows)
      {
         if (!publishedOnly)
            return GetMovies(startRowIndex, maximumRows);

         List<Movie> movies = null;
         string key = "Movies_Movies_" + publishedOnly.ToString() + "_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movies = (List<Movie>)BizObject.Cache[key];
         }
         else
         {
            List<MovieDetails> recordset = SiteProvider.Movies.GetPublishedMovies(DateTime.Now,
               GetPageIndex(startRowIndex, maximumRows), maximumRows);
            movies = GetMovieListFromMovieDetailsList(recordset);
            BaseMovie.CacheData(key, movies);
         }
         return movies;
      }

      /// <summary>
      /// Returns a collection with all published movies for the specified category
      /// </summary>
      public static List<Movie> GetMovies(bool publishedOnly, int categoryID)
      {
         return GetMovies(publishedOnly, categoryID, 0, BizObject.MAXROWS);
      }
      public static List<Movie> GetMovies(bool publishedOnly, int categoryID, int startRowIndex, int maximumRows)
      {
         if (!publishedOnly)
            return GetMovies(categoryID, startRowIndex, maximumRows);

         if (categoryID <= 0)
            return GetMovies(publishedOnly, startRowIndex, maximumRows);

         List<Movie> movies = null;
         string key = "Movies_Movies_" + publishedOnly.ToString() + "_" + categoryID.ToString() + "_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movies = (List<Movie>)BizObject.Cache[key];
         }
         else
         {
            List<MovieDetails> recordset = SiteProvider.Movies.GetPublishedMovies(
               categoryID, DateTime.Now,
               GetPageIndex(startRowIndex, maximumRows), maximumRows);
            movies = GetMovieListFromMovieDetailsList(recordset);
            BaseMovie.CacheData(key, movies);
         }
         return movies;
      }

      /// <summary>
      /// Returns the number of total published movies
      /// </summary>
      public static int GetMovieCount(bool publishedOnly)
      {
         if (publishedOnly)
            return GetMovieCount();

         int movieCount = 0;
         string key = "Movies_MovieCount_" + publishedOnly.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movieCount = (int)BizObject.Cache[key];
         }
         else
         {
            movieCount = SiteProvider.Movies.GetPublishedMovieCount(DateTime.Now);
            BaseMovie.CacheData(key, movieCount);
         }
         return movieCount;            
      }

      
      /// <summary>
      /// Returns an Movie object with the specified ID
      /// </summary>
      public static Movie GetMovieByID(int ID)
      {
         Movie movie = null;
         string key = "Movies_Movie_" + ID.ToString();

         if (BaseMovie.Settings.EnableCaching && BizObject.Cache[key] != null)
         {
            movie = (Movie)BizObject.Cache[key];
         }
         else
         {
            movie = GetMovieFromMovieDetails(SiteProvider.Movies.GetMovieByID(movieID));
            BaseMovie.CacheData(key, movie);
         }
         return movie; 
      }
//needs updating
      /// <summary>
      /// Updates an existing movie
      /// </summary>
      public static bool UpdateMovie(int id, int categoryID, string title, 
         string Abstract, string summary, string country, string state, string city,
            DateTime releaseDate, DateTime expireDate, bool approved, bool listed,
            bool commentsEnabled, bool onlyForMembers)
      {
         title = BizObject.ConvertNullToEmptyString(title);
         Abstract = BizObject.ConvertNullToEmptyString(Abstract);
         summary = BizObject.ConvertNullToEmptyString(summary);
         country = BizObject.ConvertNullToEmptyString(country);
         state = BizObject.ConvertNullToEmptyString(state);
         city = BizObject.ConvertNullToEmptyString(city);

         if (releaseDate == DateTime.MinValue)
            releaseDate = DateTime.Now;
         if (expireDate == DateTime.MinValue)
            expireDate = DateTime.MaxValue;

         MovieDetails record = new MovieDetails(id, DateTime.Now, "", categoryID,
            "", title, Abstract, summary, country, state, city, releaseDate, expireDate,
            approved, listed, commentsEnabled, onlyForMembers, 0, 0, 0);
         bool ret = SiteProvider.Movies.UpdateMovie(record);

         BizObject.PurgeCacheItems("movies_movie_" + id.ToString());
         BizObject.PurgeCacheItems("movies_movies");
         return ret;
      }
//needs updating
      /// <summary>
      /// Creates a new movie
      /// </summary>
      public static int InsertMovie(int categoryID, string title, string Abstract,
         string summary, string country, string state, string city, DateTime releaseDate, DateTime expireDate,
         bool approved, bool listed, bool commentsEnabled, bool onlyForMembers)
      {
         // ensure that the "approved" option is false if the current user is not
         // an administrator or a editor (it may be a contributor for example)
         bool canApprove = (BizObject.CurrentUser.IsInRole("Administrators") || BizObject.CurrentUser.IsInRole("Editors"));
         if (!canApprove)
            approved = false;

         title = BizObject.ConvertNullToEmptyString(title);
         Abstract = BizObject.ConvertNullToEmptyString(Abstract);
         summary = BizObject.ConvertNullToEmptyString(summary);
         country = BizObject.ConvertNullToEmptyString(country);
         state = BizObject.ConvertNullToEmptyString(state);
         city = BizObject.ConvertNullToEmptyString(city);

         if (releaseDate == DateTime.MinValue)
            releaseDate = DateTime.Now;
         if (expireDate == DateTime.MinValue)
            expireDate = DateTime.MaxValue;

         MovieDetails record = new MovieDetails(0, DateTime.Now, BizObject.CurrentUserName,
            categoryID, "", title, Abstract, summary, country, state, city, releaseDate, expireDate, 
            approved, listed, commentsEnabled, onlyForMembers, 0, 0, 0);
         int ret = SiteProvider.Movies.InsertMovie(record);

         BizObject.PurgeCacheItems("movies_movie");
         return ret;
      }

      /// <summary>
      /// Deletes an existing movie
      /// </summary>
      public static bool DeleteMovie(int id)
      {
         bool ret = SiteProvider.Movies.DeleteMovie(id);
         new RecordDeletedEvent("movie", id, null).Raise();
         BizObject.PurgeCacheItems("movies_movie");
         return ret;
      }

      /// <summary>
      /// Approves an existing movie
      /// </summary>
      public static bool ApproveMovie(int id)
      {
         bool ret = SiteProvider.Movies.ApproveMovie(id);
         BizObject.PurgeCacheItems("movies_movie_" + id.ToString());
         BizObject.PurgeCacheItems("movies_movies");
         return ret;
      }

//needs updating
      /// <summary>
      /// Returns a Movie object filled with the data taken from the input MovieDetails
      /// </summary>
      private static Movie GetMovieFromMovieDetails(MovieDetails record)
      {
         if (record == null)
            return null;
         else
         {
            return new Movie(record.ID, record.AddedDate, record.AddedBy,
               record.CategoryID, record.CategoryTitle, record.Title, record.Abstract, record.Summary,
               record.Country, record.State, record.City, record.ReleaseDate, record.ExpireDate,
               record.Approved, record.Listed, record.CommentsEnabled, record.OnlyForMembers,
               record.ViewCount, record.Votes, record.TotalRating);
         }
      }

      /// <summary>
      /// Returns a list of Movie objects filled with the data taken from the input list of MovieDetails
      /// </summary>
      private static List<Movie> GetMovieListFromMovieDetailsList(List<MovieDetails> recordset)
      {
         List<Movie> movies = new List<Movie>();
         foreach (MovieDetails record in recordset)
            movies.Add(GetMovieFromMovieDetails(record));
         return movies;
      }
   }
}